/**
 * 可视化编辑器工具类
 * 用于处理iframe与主网站的通信，实现可视化编辑功能
 */

export interface SelectedElement {
  id: string
  tagName: string
  className: string
  textContent: string
  innerHTML: string
  xpath: string
  selector: string
  position: {
    x: number
    y: number
    width: number
    height: number
  }
}

export interface VisualEditorOptions {
  iframeId: string
  onElementHover?: (element: SelectedElement | null) => void
  onElementSelect?: (element: SelectedElement | null) => void
  onElementUnselect?: () => void
}

export class VisualEditor {
  private iframe: HTMLIFrameElement | null = null
  private isEditMode = false
  private selectedElement: SelectedElement | null = null
  private options: VisualEditorOptions
  private messageHandler: ((event: MessageEvent) => void) | null = null

  constructor(options: VisualEditorOptions) {
    this.options = options
    this.init()
  }

  /**
   * 初始化编辑器
   */
  private init() {
    this.iframe = document.getElementById(this.options.iframeId) as HTMLIFrameElement
    if (!this.iframe) {
      console.error(`Iframe with id '${this.options.iframeId}' not found`)
      return
    }

    // 监听iframe消息
    this.messageHandler = (event: MessageEvent) => {
      if (event.origin !== window.location.origin) {
        return // 只接受同域名消息
      }

      const { type, data } = event.data
      switch (type) {
        case 'ELEMENT_HOVER':
          this.handleElementHover(data)
          break
        case 'ELEMENT_CLICK':
          this.handleElementClick(data)
          break
        case 'ELEMENT_UNHOVER':
          this.handleElementUnhover()
          break
      }
    }

    window.addEventListener('message', this.messageHandler)
  }

  /**
   * 进入编辑模式
   */
  enterEditMode() {
    if (!this.iframe || !this.iframe.contentWindow) {
      console.error('Iframe not ready')
      return
    }

    this.isEditMode = true
    
    // 向iframe发送进入编辑模式的消息
    this.iframe.contentWindow.postMessage({
      type: 'ENTER_EDIT_MODE'
    }, window.location.origin)

    console.log('进入编辑模式')
  }

  /**
   * 退出编辑模式
   */
  exitEditMode() {
    if (!this.iframe || !this.iframe.contentWindow) {
      return
    }

    this.isEditMode = false
    this.selectedElement = null
    
    // 向iframe发送退出编辑模式的消息
    this.iframe.contentWindow.postMessage({
      type: 'EXIT_EDIT_MODE'
    }, window.location.origin)

    // 通知上层组件
    this.options.onElementUnselect?.()
    
    console.log('退出编辑模式')
  }

  /**
   * 处理元素悬浮
   */
  private handleElementHover(elementData: any) {
    if (!this.isEditMode) return

    const element: SelectedElement = this.parseElementData(elementData)
    this.options.onElementHover?.(element)
  }

  /**
   * 处理元素点击
   */
  private handleElementClick(elementData: any) {
    if (!this.isEditMode) return

    const element: SelectedElement = this.parseElementData(elementData)
    this.selectedElement = element
    this.options.onElementSelect?.(element)
    
    console.log('选中元素:', element)
  }

  /**
   * 处理元素取消悬浮
   */
  private handleElementUnhover() {
    if (!this.isEditMode) return
    this.options.onElementHover?.(null)
  }

  /**
   * 解析元素数据
   */
  private parseElementData(data: any): SelectedElement {
    return {
      id: data.id || '',
      tagName: data.tagName || '',
      className: data.className || '',
      textContent: data.textContent || '',
      innerHTML: data.innerHTML || '',
      xpath: data.xpath || '',
      selector: data.selector || '',
      position: {
        x: data.position?.x || 0,
        y: data.position?.y || 0,
        width: data.position?.width || 0,
        height: data.position?.height || 0
      }
    }
  }

  /**
   * 获取选中的元素
   */
  getSelectedElement(): SelectedElement | null {
    return this.selectedElement
  }

  /**
   * 清除选中的元素
   */
  clearSelectedElement() {
    this.selectedElement = null
    this.options.onElementUnselect?.()
  }

  /**
   * 检查是否在编辑模式
   */
  isInEditMode(): boolean {
    return this.isEditMode
  }

  /**
   * 销毁编辑器
   */
  destroy() {
    if (this.messageHandler) {
      window.removeEventListener('message', this.messageHandler)
      this.messageHandler = null
    }
    this.selectedElement = null
    this.isEditMode = false
  }
}

/**
 * 生成元素的XPath
 */
export function getElementXPath(element: Element): string {
  if (element.id) {
    return `//*[@id="${element.id}"]`
  }
  
  const parts = []
  let current: Element | null = element
  
  while (current && current.nodeType === Node.ELEMENT_NODE) {
    let siblingIndex = 1
    let sibling = current.previousElementSibling
    
    while (sibling) {
      if (sibling.tagName === current.tagName) {
        siblingIndex++
      }
      sibling = sibling.previousElementSibling
    }
    
    const tagName = current.tagName.toLowerCase()
    const part = siblingIndex > 1 ? `${tagName}[${siblingIndex}]` : tagName
    parts.unshift(part)
    
    current = current.parentElement
  }
  
  return '/' + parts.join('/')
}

/**
 * 生成元素的CSS选择器
 */
export function getElementSelector(element: Element): string {
  if (element.id) {
    return `#${element.id}`
  }
  
  const parts = []
  let current: Element | null = element
  
  while (current && current !== document.body) {
    let selector = current.tagName.toLowerCase()
    
    if (current.className) {
      const classes = current.className.split(' ').filter(c => c.trim())
      if (classes.length > 0) {
        selector += '.' + classes.join('.')
      }
    }
    
    // 如果有兄弟元素，添加nth-child
    const siblings = Array.from(current.parentElement?.children || [])
    const index = siblings.indexOf(current)
    if (siblings.length > 1) {
      selector += `:nth-child(${index + 1})`
    }
    
    parts.unshift(selector)
    current = current.parentElement
  }
  
  return parts.join(' > ')
}

/**
 * 为iframe页面注入编辑功能的脚本
 * 这个函数需要在iframe加载完成后调用
 */
export function injectEditScript(iframeWindow: Window) {
  const script = `
    (function() {
      let isEditMode = false;
      let hoveredElement = null;
      let selectedElement = null;
      
      // 元素悬浮样式
      const hoverStyle = 'outline: 2px dashed #1890ff; outline-offset: 2px; cursor: pointer;';
      const selectedStyle = 'outline: 3px solid #1890ff; outline-offset: 2px; background-color: rgba(24, 144, 255, 0.1);';
      
      // 获取元素信息
      function getElementInfo(element) {
        const rect = element.getBoundingClientRect();
        return {
          id: element.id,
          tagName: element.tagName,
          className: element.className,
          textContent: element.textContent?.trim().substring(0, 100) || '',
          innerHTML: element.innerHTML?.substring(0, 200) || '',
          xpath: getElementXPath(element),
          selector: getElementSelector(element),
          position: {
            x: rect.left,
            y: rect.top,
            width: rect.width,
            height: rect.height
          }
        };
      }
      
      // 生成XPath
      function getElementXPath(element) {
        if (element.id) {
          return '//*[@id="' + element.id + '"]';
        }
        
        const parts = [];
        let current = element;
        
        while (current && current.nodeType === Node.ELEMENT_NODE) {
          let siblingIndex = 1;
          let sibling = current.previousElementSibling;
          
          while (sibling) {
            if (sibling.tagName === current.tagName) {
              siblingIndex++;
            }
            sibling = sibling.previousElementSibling;
          }
          
          const tagName = current.tagName.toLowerCase();
          const part = siblingIndex > 1 ? tagName + '[' + siblingIndex + ']' : tagName;
          parts.unshift(part);
          
          current = current.parentElement;
        }
        
        return '/' + parts.join('/');
      }
      
      // 生成CSS选择器
      function getElementSelector(element) {
        if (element.id) {
          return '#' + element.id;
        }
        
        const parts = [];
        let current = element;
        
        while (current && current !== document.body) {
          let selector = current.tagName.toLowerCase();
          
          if (current.className) {
            const classes = current.className.split(' ').filter(c => c.trim());
            if (classes.length > 0) {
              selector += '.' + classes.join('.');
            }
          }
          
          const siblings = Array.from(current.parentElement?.children || []);
          const index = siblings.indexOf(current);
          if (siblings.length > 1) {
            selector += ':nth-child(' + (index + 1) + ')';
          }
          
          parts.unshift(selector);
          current = current.parentElement;
        }
        
        return parts.join(' > ');
      }
      
      // 鼠标悬浮事件
      function handleMouseOver(event) {
        if (!isEditMode) return;
        
        event.stopPropagation();
        
        // 移除之前的悬浮样式
        if (hoveredElement && hoveredElement !== selectedElement) {
          hoveredElement.style.cssText = hoveredElement.style.cssText.replace(hoverStyle, '');
        }
        
        hoveredElement = event.target;
        
        // 如果不是已选中的元素，添加悬浮样式
        if (hoveredElement !== selectedElement) {
          hoveredElement.style.cssText += hoverStyle;
        }
        
        // 发送悬浮消息
        parent.postMessage({
          type: 'ELEMENT_HOVER',
          data: getElementInfo(hoveredElement)
        }, window.location.origin);
      }
      
      // 鼠标离开事件
      function handleMouseOut(event) {
        if (!isEditMode) return;
        
        event.stopPropagation();
        
        // 移除悬浮样式（但保留选中样式）
        if (hoveredElement && hoveredElement !== selectedElement) {
          hoveredElement.style.cssText = hoveredElement.style.cssText.replace(hoverStyle, '');
        }
        
        // 发送取消悬浮消息
        parent.postMessage({
          type: 'ELEMENT_UNHOVER'
        }, window.location.origin);
      }
      
      // 清除所有元素的选中和悬浮样式
      function clearAllStyles() {
        const allElements = document.querySelectorAll('*');
        allElements.forEach(element => {
          if (element.style) {
            // 移除选中样式
            element.style.cssText = element.style.cssText.replace(selectedStyle, '');
            // 移除悬浮样式
            element.style.cssText = element.style.cssText.replace(hoverStyle, '');
            // 移除所有可能的outline样式
            element.style.cssText = element.style.cssText.replace(/outline:[^;]*;?/g, '');
            // 移除所有可能的background-color样式（仅针对编辑模式添加的）
            element.style.cssText = element.style.cssText.replace(/background-color:\s*rgba\(24,\s*144,\s*255,\s*0\.1\)[^;]*;?/g, '');
          }
        });
        
        // 强制清理所有编辑相关的内联样式
        try {
          const styleElements = document.querySelectorAll('[style*="outline"], [style*="background-color"]');
          styleElements.forEach(element => {
            const style = element.getAttribute('style') || '';
            const cleanStyle = style
              .replace(/outline:[^;]*;?/g, '')
              .replace(/background-color:\s*rgba\(24,\s*144,\s*255,\s*0\.1\)[^;]*;?/g, '')
              .replace(/;\s*;/g, ';')
              .replace(/^;+|;+$/g, '');
            
            if (cleanStyle.trim()) {
              element.setAttribute('style', cleanStyle);
            } else {
              element.removeAttribute('style');
            }
          });
        } catch (error) {
          console.warn('清理样式时出错:', error);
        }
      }
      
      // 点击事件
      function handleClick(event) {
        if (!isEditMode) return;
        
        event.preventDefault();
        event.stopPropagation();
        
        // 清除所有元素的样式，确保只有当前选中的元素显示选中状态
        clearAllStyles();
        
        selectedElement = event.target;
        
        // 添加选中样式
        selectedElement.style.cssText += selectedStyle;
        
        // 发送选中消息
        parent.postMessage({
          type: 'ELEMENT_CLICK',
          data: getElementInfo(selectedElement)
        }, window.location.origin);
      }
      
      // 进入编辑模式
      function enterEditMode() {
        isEditMode = true;
        document.body.style.userSelect = 'none';
        
        // 添加事件监听器
        document.addEventListener('mouseover', handleMouseOver, true);
        document.addEventListener('mouseout', handleMouseOut, true);
        document.addEventListener('click', handleClick, true);
        
        console.log('iframe进入编辑模式');
      }
      
      // 退出编辑模式
      function exitEditMode() {
        isEditMode = false;
        document.body.style.userSelect = '';
        
        // 移除事件监听器
        document.removeEventListener('mouseover', handleMouseOver, true);
        document.removeEventListener('mouseout', handleMouseOut, true);
        document.removeEventListener('click', handleClick, true);
        
        // 清除所有元素的样式
        clearAllStyles();
        
        hoveredElement = null;
        selectedElement = null;
        
        console.log('iframe退出编辑模式');
      }
      
      // 监听来自父窗口的消息
      window.addEventListener('message', function(event) {
        if (event.origin !== window.location.origin) return;
        
        const { type } = event.data;
        switch (type) {
          case 'ENTER_EDIT_MODE':
            enterEditMode();
            break;
          case 'EXIT_EDIT_MODE':
            exitEditMode();
            break;
          case 'FORCE_CLEAR_STYLES':
            // 强制清理所有编辑样式
            console.log('收到强制清理样式消息');
            clearAllStyles();
            isEditMode = false;
            hoveredElement = null;
            selectedElement = null;
            document.body.style.userSelect = '';
            break;
        }
      });
    })();
  `;
  
  // 创建script元素并注入
  const scriptElement = iframeWindow.document.createElement('script')
  scriptElement.textContent = script
  iframeWindow.document.head.appendChild(scriptElement)
}
